﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using SQLQuery.UI;
using DevExpress.Xpf.Docking;
using SQLQuery.ViewModel;
using SQLQuery.Common;
using QueryResource.ViewModel;
using DevExpress.Xpf.Ribbon;
using DevExpress.Xpf.Bars;
using DevExpress.Utils;
using System.IO;
using Skynet.CommonLibrary.Extension;
using System.Threading.Tasks;
using DevExpress.Xpf.Core;
using System.Windows.Media;

namespace SQLQuery
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : DXWindow
    {
        public MainWindow()
        {
           
                InitializeComponent();
                this.WindowState = System.Windows.WindowState.Maximized;
                this.Closed += new EventHandler(MainWindow_Closed);
                this.Loaded += new RoutedEventHandler(RibbonMainWindow_Loaded);
            
        }

        public MainViewModel ViewModel { get; set; }
        public DBTreeViewModel TreeViewModel { get; set; }
        //数据对比
        public DataComparsionViewModel ComparsionViewModel { get; set; }

        public BitmapImage GetImageSource(string ItemPath)
        {
            BitmapImage img = new BitmapImage();
            img.BeginInit();

            img.CacheOption = BitmapCacheOption.OnLoad;
            img.UriSource = new Uri("pack://application:,,,/" + System.Reflection.Assembly.GetExecutingAssembly().FullName + ";component/" + ItemPath);
            img.EndInit();
            img.Freeze();
            return img;
        }

        #region 工具栏
        protected virtual void OnThemeDropDownGalleryInit(object sender, DropDownGalleryEventArgs e)
        {
            Gallery gallery = e.DropDownGallery.Gallery;
            gallery.AllowHoverImages = false;
            gallery.IsItemCaptionVisible = true;
            gallery.ItemGlyphLocation = Dock.Top;
            gallery.IsGroupCaptionVisible = DefaultBoolean.True;
        }
        protected virtual void OnThemeItemClick(object sender, GalleryItemEventArgs e)
        {
            string themeName = (string)e.Item.Caption;
            themeName = themeName.Replace(" ", string.Empty);
            ViewModel.SkinChanged(this,themeName);
        }
        //新建数据源
        private void CreateDB_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.CreateDBExecuted();
        }
        //拷贝字段名
        private void CopyFieldName_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.CopyFieldNameExecuted();
        }
        //格式刷
        private void TxtFormat_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ViewModel.TxtFormatCanExecute();
        }
        private void TxtFormat_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.TxtFormatExecuted();
        }
        //打开文件
        private void FileOpen_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.FileOpenExecuted();
        }
        //保存文件
        private void FileSave_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.FileSaveCommand.Execute(null);
        }
        private void FileSave_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ViewModel.FileSaveCommand.CanExecute(null);
        }
        //运行
        private void RunSQL_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.RunSqlExecuted();
        }
        private void RunSQL_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = ViewModel.RunSqlCanExecute();
        }
        //删除数据源
        private void DelDB_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TreeViewModel.DeleteCommand.Execute(TreeViewModel.SelectedItem);
        }
        private void DelDB_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (TreeViewModel == null)
                e.CanExecute = false;
            else
            {
                e.CanExecute = TreeViewModel.DeleteCommand.CanExecute(null);
            }
        }
        //连接
        private void ConnectionDB_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TreeViewModel.ConnectDBCommand.Execute(TreeViewModel.SelectedItem);
        }
        private void ConnectionDB_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (TreeViewModel == null)
                e.CanExecute = false;
            else
            {
                e.CanExecute = TreeViewModel.ConnectDBCommand.CanExecute(null);
            }
        }
        //断开连接
        private void UnConnectionDB_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TreeViewModel.UnConnectDBCommand.Execute(TreeViewModel.SelectedItem);
        }
        private void UnConnectionDB_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (TreeViewModel == null)
                e.CanExecute = false;
            else
            {
                e.CanExecute = TreeViewModel.UnConnectDBCommand.CanExecute(null);
            }
        }
        //清空
        private void TxtClear_CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ViewModel.ClearCommand.Execute(null);
        }
        private void TxtClear_CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (TreeViewModel == null)
                e.CanExecute = false;
            else
            {
                e.CanExecute = ViewModel.ClearCommand.CanExecute(null);
            }
        }

        //更新
        private void bUpdate_ItemClick(object sender, ItemClickEventArgs e)
        {
            try
            {
                System.Reflection.AssemblyName name = System.Reflection.AssemblyName.GetAssemblyName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                if (UpdateHelper.IsDown(name.Version.ToString(), System.IO.Path.GetFileName(name.CodeBase)))
                {
                    if (File.Exists("Update.exe"))
                    {
                        "Update.exe".StartProcessEx(System.IO.Path.GetFileName(name.CodeBase), Directory.GetCurrentDirectory());
                    }
                    else
                    {
                        SQLQuery.Common.MessageBoxHelper.Show("更新程序不存在，无法进行更新。");
                    }
                }
                else
                {
                    SQLQuery.Common.MessageBoxHelper.Show("已经是最新版本了");
                }
            }
            catch (Exception ex)
            {
                SQLQuery.Common.MessageBoxHelper.Show("无法连接到更新服务器，无法更新。\r详细:" + ex.Message);
            }
        }
        #endregion
        #region
        private void dockManager_DockItemClosed(object sender, DevExpress.Xpf.Docking.Base.DockItemClosedEventArgs e)
        {

            LayoutPanel panel = e.Item as LayoutPanel;
            if (e.Item is LayoutGroup)
            {
                panel = (e.Item as LayoutGroup).Items[0] as LayoutPanel;
            }
            SQLControl sql = panel.Content as SQLControl;
            if (sql != null)
            {
                sql.ViewModel.AppendLogAction = null;
                sql.ViewModel.AppendDataAction = null;
                sql.ViewModel = null;
            }
            else
            {
                GridViewControl control = panel.Content as GridViewControl;
                if (control != null)
                {
                    control.AppendLogAction = null;
                    control.AppendDataSucess = null;
                    control.AppendSqlContent = null;
                }
            }
        }
        void RibbonMainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Init();
        }
        void MainWindow_Closed(object sender, EventArgs e)
        {
            this.dbtreeview.ViewModel.WriteData();

            DocumentPanel panel = documentGroup.Items[0] as DocumentPanel;
            SQLControl control = panel.Content as SQLControl;
            if (control != null)
            {
                string path = System.AppDomain.CurrentDomain.BaseDirectory + "\\";
                if (panel.Caption.IndexOf("*") > 0)
                {
                    path += panel.Caption.Remove(panel.Caption.Length - 1) + ".dat";
                    control.SaveFile(path);
                }
            }
        }
        private void ribbonControl1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                this.DragMove();
            }
        }

        private void btnclose_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
        {
            this.Close();
        }

        private void btnmin_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
        {
            this.WindowState = System.Windows.WindowState.Minimized;
        }

        private void btnmax_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
        {
            if (this.WindowState == System.Windows.WindowState.Maximized)
            {
                this.WindowState = System.Windows.WindowState.Normal;
            }
            else
            {
                this.WindowState = System.Windows.WindowState.Maximized;
            }
        }
        #endregion

        #region
        #region 交互
        private void ShowNewWindow(string caption, string content)
        {
            DocumentPanel panel = new DocumentPanel();
            panel.Caption = caption;

            SQLControl control = new SQLControl();
            control.ViewModel.AppendLogAction = ShowLog;
            control.ViewModel.AppendDataAction = ShowDS;
            control.Init(false, false);
            panel.Content = control;
            this.documentGroup.Items.Add(panel);

            this.dockManager.LayoutController.Activate(panel);
            if (!string.IsNullOrEmpty(content))
            {
                control.AppendCmd(content);
            }
        }
        private void ShowNewWindowLoadFile(string caption, string content, bool isFile)
        {
            DocumentPanel panel = new DocumentPanel();
            panel.Caption = caption;

            SQLControl control = new SQLControl();
            control.ViewModel.AppendLogAction = ShowLog;
            control.ViewModel.AppendDataAction = ShowDS;
            if (isFile)
            {
                control.Init(false);
                control.LoadFile(content);
            }
            else
            {
                control.Init(false, false);
                control.AppendCmd(content);
            }

            panel.Content = control;
            this.documentGroup.Items.Add(panel);
            this.dockManager.LayoutController.Activate(panel);

        }

        private void ShowSQL(string sql, bool isRun, bool isNewLine)
        {
            if (!this.documentSQL.IsActive)
            {
                this.dockManager.LayoutController.Activate(documentSQL);
            }
            this.sqlcontrol.ViewModel.ExecAppendCmd(sql, isRun, isNewLine);
        }

        private void ShowLog(string msg, Color errorColor)
        {
            if (errorColor != Colors.Black)
            {
                this.InvokeEx(new Action(() =>
                {
                    if (!this.documentLog.IsActive)
                    {
                        this.dockManager.LayoutController.Activate(documentLog);
                    }
                }));
            }
            this.logcontrol.WriteLog(msg, errorColor);
        }

        private void ShowDS(string sql)
        {
            this.BeginInvokeEx(new Action(() =>
            {
                GridViewControl control = GetNoBusyGridControl(true);
                if (control != null)
                {
                    control.DataBind(sql);
                }
                else
                {
                    LayoutGroup group = this.documentDS.Parent as LayoutGroup;
                    if (group == null)
                    {
                        GridViewControl gridcontrol = documentDS.Content as GridViewControl;
                        if (gridcontrol.IsBusy)
                        {
                            ShowLog("正在查询中……", Colors.Blue);
                        }
                        else
                        {
                            gridcontrol.DataBind(sql);
                        }
                    }
                    else
                    {
                        ////新增一个窗体
                        LayoutPanel panel = new LayoutPanel();
                        panel.Caption = "数据";

                        control = new GridViewControl();
                        control.AppendLogAction = ShowLog;
                        control.AppendDataSucess = ShowDataSucess;
                        control.AppendSqlContent = ShowNewWindowLoadFile;
                        panel.Content = control;
                        group.Items.Add(panel);
                        this.dockManager.LayoutController.Activate(panel);
                        control.DataBind(sql);
                    }
                }
            }));
        }

        private void ShowDBInfo(string ip, string dbname, string userid)
        {
            this.BeginInvokeEx(new Action(() =>
            {
                this.lbIPname.Content = "数据库IP：" + ip;
                this.lbDBname.Content = string.Format("数据库名称:{0}", dbname.Replace("_", "__"));
                this.lbUserId.Content = "当前用户:" + userid;
            }), null);
        }

        private void ShowFieldCaption(string caption)
        {
            this.lbFieldName.BeginInvokeEx(new Action(() =>
            {
                this.lbFieldName.Content = "说明：" + caption;
            }), null);
        }

        private void ShowDataSucess(GridViewControl control)
        {
            LayoutPanel panel = control.Tag as LayoutPanel;
            if (panel != null)
            {
                this.dockManager.LayoutController.Activate(panel);
            }
        }

        #endregion

        /// <summary>
        /// 获得当前激活的 Document
        /// </summary>
        /// <returns></returns>
        private DocumentPanel GetActiveSQLControl(ref SQLControl control)
        {
            foreach (DocumentPanel panel in (this.documentSQL.Parent as LayoutGroup).Items)
            {
                if (!panel.IsActive)
                    continue;
                SQLControl sqlcontrol = panel.Content as SQLControl;
                if (sqlcontrol != null)
                {
                    control = sqlcontrol;
                    return panel;
                }
            }
            return null;
        }
        /// <summary>
        /// 返回一个闲置的Grid 如果没有 则返回NUll
        /// </summary>
        /// <returns></returns>
        private GridViewControl GetNoBusyGridControl(bool isActive)
        {
            LayoutGroup group = this.documentDS.Parent as LayoutGroup;
            GridViewControl gc = null;
            if (group != null)
            {
                List<LayoutPanel> removes = new List<LayoutPanel>();
                foreach (LayoutPanel panel in group.Items)
                {
                    GridViewControl gridcontrol = panel.Content as GridViewControl;
                    if (gridcontrol != null)
                    {
                        if (!gridcontrol.IsBusy)
                        {
                            if (isActive)
                            {
                                this.dockManager.LayoutController.Activate(panel);
                            }
                            if (gc != null)
                            {
                                removes.Add(panel);
                            }
                            else
                            {
                                gc = gridcontrol;
                            }
                        }
                    }
                }
                removes.ForEach(o => group.Items.Remove(o));
            }
            return gc;
        }
        /// <summary>
        /// 获取当前激活的SQL编辑框
        /// </summary>
        /// <returns></returns>
        private SQLControl GetActiveSQLControl()
        {
            SQLControl sql = null;
            GetActiveSQLControl(ref sql);
            return sql;
        }
        #endregion

        private void Init()
        {
            
                ViewModel = new MainViewModel(this.dbtreeview.ViewModel);
                TreeViewModel = this.dbtreeview.ViewModel;
                DataContext = this;

                ViewModel.GetActiveSqlControl = GetActiveSQLControl;
                ViewModel.GetActiveSqlPanel += GetActiveSQLControl;
                ViewModel.ShowNewWindowLoadFile = ShowNewWindowLoadFile;

                TreeViewModel.AppendSqlAction = ShowSQL;
                TreeViewModel.AppendLogAction = ShowLog;
                TreeViewModel.AppendWindow = ShowNewWindow;
                TreeViewModel.AppendDBInfo = ShowDBInfo;
                TreeViewModel.AppendFieldCaption = ShowFieldCaption;

                this.sqlcontrol.ViewModel.AppendLogAction = ShowLog;
                this.sqlcontrol.ViewModel.AppendDataAction = ShowDS;

                this.gridviewcontrol.AppendLogAction = ShowLog;
                this.gridviewcontrol.AppendDataSucess = ShowDataSucess;
                this.gridviewcontrol.AppendSqlContent = ShowNewWindowLoadFile;

                ComparsionViewModel = new DataComparsionViewModel();
                ComparsionViewModel.AppendLogAction = ShowLog;
                ComparsionViewModel.ViewInvoke = act => { this.InvokeEx(act); };

                //初始化
                this.dbtreeview.Init();
                this.sqlcontrol.Init(true);
                ViewModel.ReadTheme(this);

                UpdateTip();

            
        }

        /// <summary>
        /// 获取更新信息
        /// </summary>
        private void UpdateTip()
        {
            Func<string> action = () =>
            {
                System.Reflection.AssemblyName name = System.Reflection.AssemblyName.GetAssemblyName(System.Reflection.Assembly.GetExecutingAssembly().Location);

                try
                {
                    if (UpdateHelper.IsDown(name.Version.ToString(), System.IO.Path.GetFileName(name.CodeBase)))
                    {
                        return "有新版本可以更新了，请猛击更新按钮，获取最新程序。";
                    }
                    else
                    {
                        return "当前版本:" + name.Version.ToString();
                    }
                }
                catch { 
                    return "当前版本:" + name.Version.ToString();
                }
            };
            Task<string>.Factory.FromAsync(action.BeginInvoke, action.EndInvoke, null)
                .ContinueWith(t => {

                    this.lbUpdateInfo.InvokeEx(new Action(() =>
                    {
                        this.lbUpdateInfo.Content = t.Result;
                    }));
                });
        }
    }
}
